/*
 * Copyright (C) 2003-2009 eXo Platform SAS.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.reflext.test;

import junit.framework.TestCase;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
 * @version $Revision$
 */
public abstract class AbstractReflextTestCase extends TestCase {


  /** . */
  protected final Set<Class<?>> classes = new HashSet<Class<?>>();

  protected abstract void configure();

  protected abstract ReflextUnitTest getUnitTest();

  protected final void add(Class clazz) {
    classes.add(clazz);
  }

  /** . */
  private static List<UnitTestPlugin> plugins;

  private static List<UnitTestPlugin> getPlugins() throws Exception {
    if (plugins == null) {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      String path = "META-INF/services/" + UnitTestPlugin.class.getName();
      Enumeration<URL> e = cl.getResources(path);
      List<UnitTestPlugin> list = new ArrayList<UnitTestPlugin>();
      while (e.hasMoreElements()) {
        URL url = e.nextElement();
        InputStream in = new BufferedInputStream(url.openStream());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int i = in.read();i != -1;i = in.read()) {
          baos.write(i);
        }
        in.close();
        baos.close();
        String fqn = baos.toString().trim();
        Class<?> clazz = cl.loadClass(fqn);
        UnitTestPlugin plugin = (UnitTestPlugin)clazz.newInstance();
        list.add(plugin);
        plugins = list;
      }
    }
    return plugins;
  }

  public void testExecute() throws Exception {

    //
    configure();

    //
    ReflextUnitTest unitTest = getUnitTest();

    //
    for (UnitTestPlugin plugin : getPlugins()) {
      plugin.execute(unitTest, classes);
    }
  }
}
